<template>
  <h1>TodoList</h1>
  <div class="input-box">
    <span @click="selectAll">全选</span>
    <input type="text" placeholder="What's your next todo?"
      @keyup.enter="addTodo"
      v-model="text">
  </div>
  <ul class="todo-list">
    <li v-for="(todo,index) in todos" :key="index">
      <div v-if="!todo.editing" class="view" @dblclick="editTodo(index)">
        <span class="check-box" @click="selectTodo(index)"
          :class="{'selected': todo.selected}"></span>
        <div class="content">{{ todo.content }}</div>
        <span class="btn-delete" @click="removeTodo(index)">delete</span>
      </div>
      <input class="editing" v-else type="text" v-model="todo.content"
        @keyup.enter="changeContent(index)"
        @blur="changeContent(index)">
    </li>
  </ul>
  <div class="options">
    <span class="btn-clear-selected" @click="removeAllSelected">清除全部已选</span>
  </div>
</template>

<script lang="ts">
import { onUnmounted, Ref, ref } from 'vue'

/**
 * 添加代办
 * vue3中，这样的一个模块就是一整个功能的实现
 * 包括响应式数据，功能中包含的方法，最后都要return出去
 * todos参数与add功能不相关，所以要从外部引入
 */
interface Todos {
  content: string,
  selected: boolean,
  editing: boolean
}
const useAdd = (todos: Ref) => {
  const text = ref('')
  const addTodo = () => {
    if (text.value && text.value.trim()) {
      todos.value.unshift({
        content: text.value,
        selected: false,
        editing: false
      })
      text.value = ''
    }
  }
  console.log(todos, 'todos')
  return {
    text,
    addTodo
  }
}

const useRemove = (todos: Ref) => {
  const removeTodo = (index: number) => {
    todos.value.splice(index, 1)
  }
  const removeAllSelected = () => {
    todos.value = todos.value.filter((todo: Todos) => !todo.selected)
  }
  return {
    removeTodo,
    removeAllSelected
  }
}

const useEdit = (todos: Ref) => {
  const editTodo = (index: number) => {
    console.log(todos, index)
    todos.value[index].editing = true
  }
  const changeContent = (index: number) => {
    todos.value[index].editing = false
  }
  return {
    editTodo,
    changeContent
  }
}

const useSelected = (todos: Ref) => {
  const selectTodo = (index: number) => {
    todos.value[index].selected = !todos.value[index].selected
  }
  const selectAll = () => {
    todos.value.forEach((todo: Todos) => {
      todo.selected = true
    })
  }
  return {
    selectTodo,
    selectAll
  }
}

export default {
  name: 'App',

  setup (): unknown {
    const todos = ref([])

    onUnmounted(() => {
      console.log(todos, 'unmounted')
    })

    return {
      ...useAdd(todos),
      ...useRemove(todos),
      ...useEdit(todos),
      ...useSelected(todos),
      todos
    }
  }

}
</script>

<style lang="less">
.input-box {
  width: 50%;
  margin: 0 auto;
  line-height: 60px;
  text-align: left;
  span {
    margin-right: 15px;
    cursor: pointer;
  }
  input {
    border-width: 0 0 1px 0;
    height: 60px;
    width: 80%;
    font-size: 20px;
    outline: none;
    &::placeholder {
      font-size: 20px;
    }
  }
}

.todo-list {
  list-style: none;
  width: 50%;
  margin: 0 auto;
  font-size: 20px;
  text-align: left;
  padding: 0;
  li {
    line-height: 60px;
    .editing {
      border-width: 0 0 1px 0;
      height: 60px;
      width: 80%;
      font-size: 20px;
      outline: none;
    }
    .check-box {
      display: inline-block;
      vertical-align: middle;
      width: 10px;
      height: 10px;
      border: 1px solid #000;
      border-radius: 50%;
      margin: 0 10px;
    }
    .selected {
      background: #000;
    }
    .content {
      width: 80%;
      display: inline-block;
    }
    .btn-delete {
      font-size: 14px;
      cursor: pointer;
    }
  }
}

.todo-list li.editing .edit {
  display: inline-block;
}

</style>
